/**
 * 弹框组件
 * Created by zzh on 2024/2/29.
 * 待优化 解决层级问题
 * 待bug修改 图标问题
 * 待优化 自成独立组件
 * body部分滚动条样式问题
 */
define(function (require, exports, module) {
    "use strict";

    const tpl = require("./layer.html");
    const mapWritableState = Pinia.mapWritableState;
    const useSysStore = require('store/modules/sysStore');
    let index = 1, tempDiv = null;

    module.exports = {
        name: 'Layer',
        template: tpl,
        emit: ['move', 'resize'],
        props: {
            title: {
                type: String,
                default() {
                    return ""
                }
            },
            offset: {
                type: Object,
                default() {
                    return {}
                }
            },
            area: {
                type: Object,
                default() {
                    return {}
                }
            },
            visible: {
                type: Boolean,
                default: false
            },
            resizeable: {
                type: Boolean,
                default: true
            },
            fullScreenable: {
                type: Boolean,
                default: true
            },
            moveable: {
                type: Boolean,
                default: true
            },
        },
        data() {
            return {
                ide: -1,
                inited: false,
                isShow: false,
                isFullScreen: false,
                _styleCache: {
                    'right': '',
                    'left': '',
                    'bottom': '',
                    'top': '',
                    'width': '',
                    'height': '',
                    'border-radius': '',
                },
                layerStyle: {
                    'right': '',
                    'left': '',
                    'bottom': '',
                    'top': '',
                    'width': '',
                    'height': '',
                    'min-width': '200px',
                    'min-height': '134px',
                    '_dw': 0,
                    '_dh': 0,
                },
                bdStyle: {
                    'width': '',
                    'height': '',
                    '_dw': 0,
                    '_dh': 0,
                },
            }
        },
        computed: {
            ...mapWritableState(useSysStore, ['actIde']),
            isAct() {
                return this.actIde == this.ide;
            },
            isVisible: {
                get() {
                    return this.inited && this.isShow;
                },
                set(n) {
                    n && !this.inited && (this.inited = n);
                    this.isShow = n;
                }
            }
        },
        watch: {
            visible(n, o) {
                this.isVisible = n;
            },
            inited(n, o) {
                if (n) {
                    this.$nextTick(() => { this.init() })
                }
            }
        },
        mounted() {
            this.visible && (this.isVisible = this.visible);
        },
        methods: {
            /**
             * 组件初始化
            */
            init() {
                if (this.ide < 0) {
                    this.ide = index++;
                }
                this.calStyle();
                this.updatePosition(this.offset);
                this.updateBdStyle();
            },
            /**
             * 计算样式
            */
            calStyle() {
                const layer = this.$refs.layer;
                const bd = this.$refs.bd;
                this.layerStyle._dw = layer.offsetWidth - layer.clientWidth;
                this.layerStyle._dh = layer.offsetHeight - layer.clientHeight;
                this.bdStyle._dw = bd.offsetWidth - bd.clientWidth;
                this.bdStyle._dh = bd.offsetHeight - bd.clientHeight;
                if (this.area['min-width'] >= 0) {
                    this.layerStyle['min-width'] = this.area['min-width'];
                }
                if (this.area['min-height'] >= 0) {
                    this.layerStyle['min-height'] = this.area['min-height'];
                }
                this.layerStyle.width = this.area.width >= 0 ? `${this.area.width}px` : this.layerStyle['min-width'];
                this.layerStyle.height = this.area.height >= 0 ? `${this.area.height}px` : this.layerStyle['min-height'];
            },
            /**
             * 更新位置
            */
            updatePosition(offset = {}) {
                if (!this.inited) {
                    return;
                }
                const layer = this.$refs.layer;
                let top = (document.documentElement.clientHeight - layer.offsetHeight) / 2;
                let left = (document.documentElement.clientWidth - layer.offsetWidth) / 2;
                this.layerStyle.top = '';
                this.layerStyle.bottom = '';
                this.layerStyle.left = '';
                this.layerStyle.left = '';
                if (offset && offset.top >= 0) {
                    this.layerStyle.top = `${offset.top}px`;
                } else if (offset && offset.bottom >= 0) {
                    this.layerStyle.bottom = `${offset.bottom}px`;
                } else {
                    if (top < 0) top = 0;
                    this.layerStyle.top = `${top}px`;
                }
                if (offset && offset.left >= 0) {
                    this.layerStyle.left = `${offset.left}px`;
                } else if (offset && offset.right >= 0) {
                    this.layerStyle.right = `${offset.right}px`;
                    this.layerStyle.left = '';
                } else {
                    if (left < 0) left = 0;
                    this.layerStyle.left = `${left}px`;
                }
                this.updateStyle();
                this.onActive();
            },
            /**
             * 设置为活动弹窗
            */
            onActive(event) {
                this.actIde = this.ide;
            },
            /**
             * 打开/关闭 弹框
            */
            trigger() {
                this.isVisible = !this.isVisible;
            },
            /**
             * 移动组件，监听鼠标按下事件
            */
            onMove(event) {
                if (!this.moveable || this.isFullScreen) {
                    return;
                }
                const that = this;
                const layer = that.$refs.layer;
                const gap = that.showTempDiv();
                event = event || window.event;
                let dLeft = event.clientX - layer.offsetLeft;
                let dTop = event.clientY - layer.offsetTop;
                let maxLeft = layer.offsetParent.clientWidth - layer.offsetWidth;// - gap.dw;
                let maxTop = layer.offsetParent.clientHeight - layer.offsetHeight;// - gap.dh;
                document.onselectstart = function () {
                    return false;
                }
                document.onmousemove = function (event) {
                    event = event || window.event;
                    let left = event.clientX - dLeft;
                    let top = event.clientY - dTop;
                    if (left <= 0) {
                        left = 0;
                    } else if (left > maxLeft) {
                        left = maxLeft;
                    }
                    if (top <= 0) {
                        top = 0;
                    } else if (top > maxTop) {
                        top = maxTop;
                    }
                    that.changStyleTempDiv({ 'left': `${left}px`, 'top': `${top}px` });
                }
                document.onmouseup = function () {
                    document.onmousemove = null;
                    document.onmouseup = null;
                    document.onselectstart = null;
                    that.hideTempDiv();
                    that.$emit('move');
                }
            },
            /**
             * 改变组件大小，监听鼠标按下事件
            */
            onResize(event) {
                if (this.isFullScreen) {
                    return;
                }
                const that = this;
                const layer = that.$refs.layer;
                that.showTempDiv();
                let minHeight = parseInt(this.layerStyle['min-height']);
                let minWidth = parseInt(this.layerStyle['min-width']);
                document.onselectstart = function () {
                    return false;
                }
                document.onmousemove = function (event) {
                    event = event || window.event;
                    let width = event.clientX - layer.offsetLeft;
                    let height = event.clientY - layer.offsetTop;
                    if (width < minWidth) {
                        width = minWidth;
                    }
                    if (height < minHeight) {
                        height = minHeight;
                    }
                    that.changStyleTempDiv({ 'width': `${width}px`, 'height': `${height}px` });
                }
                document.onmouseup = function () {
                    document.onmousemove = null;
                    document.onmouseup = null;
                    document.onselectstart = null;
                    that.hideTempDiv();
                    that.updateBdStyle();
                }
            },
            /**
             * 显示临时边框
            */
            showTempDiv() {
                const layer = this.$refs.layer;
                if (tempDiv == null) {
                    tempDiv = document.createElement('DIV');
                    tempDiv.setAttribute("class", "layer-temp");
                } else if (tempDiv.layerId != this.ide) {
                    tempDiv.parentNode.removeChild(tempDiv);
                }
                tempDiv.layerId = this.ide;
                layer.offsetParent.appendChild(tempDiv);
                tempDiv.style.top = `${layer.offsetTop}px`;
                tempDiv.style.left = `${layer.offsetLeft}px`;
                tempDiv.style.width = `${layer.clientWidth}px`;
                tempDiv.style.height = `${layer.clientHeight}px`;
                tempDiv.style.display = 'block';
                return {
                    dw: tempDiv.offsetWidth - tempDiv.clientWidth,
                    dh: tempDiv.offsetHeight - tempDiv.clientHeight
                }
            },
            /**
             * 隐藏临时边框
            */
            hideTempDiv() {
                const layer = this.$refs.layer;
                if (this.layerStyle.bottom) {
                    this.layerStyle.bottom = `${layer.offsetParent.clientHeight - layer.offsetHeight - tempDiv.offsetTop}px`;
                } else {
                    this.layerStyle.top = tempDiv.style.top;
                }
                if ((layer.offsetParent.clientWidth / 2 - tempDiv.offsetLeft) >= (tempDiv.offsetWidth / 2)) {
                    this.layerStyle.left = tempDiv.style.left;
                    this.layerStyle.right = '';
                } else {
                    this.layerStyle.left = '';
                    this.layerStyle.right = `${tempDiv.offsetParent.clientWidth - tempDiv.offsetWidth - tempDiv.offsetLeft}px`;
                }
                this.layerStyle.width = `${tempDiv.clientWidth}px`;
                this.layerStyle.height = `${tempDiv.clientHeight}px`;
                tempDiv.style.display = 'none';
                this.updateStyle();
            },
            /**
             * 修改临时边框样式属性
            */
            changStyleTempDiv(style) {
                if (style instanceof Object) {
                    Object.assign(tempDiv.style, style);
                }
            },
            /**
             * 全屏显示切换
            */
            onFullScreen() {
                if (this.isFullScreen) {
                    this.updateLayerStyle();
                } else {
                    const layer = this.$refs.layer;
                    if (this.layerStyle.right) {
                        this.layerStyle.right = '0px';
                        this.layerStyle.left = '';
                    } else if (this.layerStyle.left) {
                        this.layerStyle.right = '';
                        this.layerStyle.left = '0px';
                    }
                    if (this.layerStyle.bottom) {
                        this.layerStyle.bottom = '0px';
                        this.layerStyle.top = '';
                    } else if (this.layerStyle.top) {
                        this.layerStyle.bottom = '';
                        this.layerStyle.top = '0px';
                    }
                    this.layerStyle.width = `${layer.offsetParent.clientWidth - this.layerStyle._dw}px`;
                    this.layerStyle.height = `${layer.offsetParent.clientHeight - this.layerStyle._dh}px`;
                    this.layerStyle['border-radius'] = '0px';
                }
                this.isFullScreen = !this.isFullScreen;
                this.updateBdStyle();
            },
            /**
             * 缓存layer样式
            */
            updateStyle() {
                const layer = this.$refs.layer;
                for (var param in this._styleCache) {
                    if (this.layerStyle[param]) {
                        this._styleCache[param] = this.layerStyle[param];
                    } else {
                        this._styleCache[param] = layer.style[param];
                    }
                }
            },
            /**
             * 更新layer样式
            */
            updateLayerStyle() {
                const layer = this.$refs.layer;
                for (var param in this._styleCache) {
                    if (this.layerStyle[param]) {
                        this.layerStyle[param] = this._styleCache[param];
                    } else {
                        layer.style[param] = this._styleCache[param];
                    }
                }
            },
            /**
             * 更新body样式
            */
            updateBdStyle() {
                const layer = this.$refs.layer;
                const hd = this.$refs.hd;
                const ft = this.$refs.ft;
                var width = 0, height = 0;
                if (layer.offsetParent) {
                    width = parseInt(this.layerStyle.width) - this.bdStyle._dw;
                    height = parseInt(this.layerStyle.height) - hd.offsetHeight - ft.offsetHeight - this.bdStyle._dh;
                } else {
                    width = parseInt(this.layerStyle.width) - 2;
                    height = parseInt(this.layerStyle.height) - 30 - ft.offsetHeight - 2;
                }
                if (height < 0) {
                    height = 0;
                }
                this.bdStyle.width = `${width}px`;
                this.bdStyle.height = `${height}px`;
                this.$emit("resize", width, height);
            },
        }
    }
})